Generador numeros aleatorios

Contenido

Como generar números (pseudo)-aleatorios en microcontroladores AVR.

Usaremos el timer1 del microcontrolador para que cuente entre 0 y 65535, cuando se produzca una entrada del usuario obtendremos el valor del timer1 para conseguir el numero pseudo-aleatorio, y hacemos los calculos (módulo y sumar), para que el valor esté entre el rango que quiera el usuario.

En este ejemplo el numero resultante se muestra en binario usando leds.

IMPORTANTE: es imprescindible que la función get_random() sea llamada en base a una entrada del usuario, si se llama de manera automátizada desde el código se perderá entropia y los numeros podrían ser mas predecibles.

Circuito

Circuito SimulIDE

Código
#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h>

void timer1_init() {
    TCCR1B |= (1 << WGM12); // Modo CTC
    TCCR1B |= (1 << CS10); // Sin preescaler
    OCR1A = 65535;
}

int get_random(int a, int b){
    int numberDiff = b - a + 1;
    return (TCNT1 % numberDiff) + a; //Usamos el timer1 para obtener un valor y hacemos los calculos para que esté en el rango que se ha indicado
}

ISR(INT0_vect) {
    PORTB = get_random(5,16);
    _delay_ms(500);
    
    EIFR |= (1 << INTF0); //eliminamos posibles interrupciones generadas durante el ISR
}

int main(void) {
    DDRB = 0xFF; //Todos los puertos del registro B como salida
    PORTD |= (1 << PD2); // pull-up resistor en PD2

    EIMSK |= (1 << INT0); //Activamos INT0 para interrupciones
    EICRA |= (1 << ISC00); //Generamos interrupción cuando haya un cambio en el puerto
    sei(); //Activamos interrupciones globalmente

    timer1_init(); // Inicializar Timer1

    while (1) {
        PORTB = 0x00; //Apagamos leds
    }
}
Tags

AVR | Random